﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace IURIP
{
    /// <summary>
    /// The task object. A task means URIP will run once to extract and ppopulate all data from source system to destination system.
    /// </summary>
    public interface ITask
    {
        /// <summary>
        /// Gets the targets defined in the target configuration file
        /// </summary>
        Dictionary<string, ITarget> Targets { get; }
        /// <summary>
        /// Gets the abstractor defined in task configuration file
        /// </summary>
        IAbstractor Abstractor { get; }
        /// <summary>
        /// Gets the propagator defined in task configuration file
        /// </summary>
        IPropagator Propagator { get; }
        /// <summary>
        /// Gets the TargetRelationships defined in the task
        /// </summary>
        List<ITargetRelationship> TargetRelationships { get; }

        /// <summary>
        /// Gets the list of process that will run late.
        /// </summary>
        Queue<IProcess> Processes { get; }
        /// <summary>
        /// Gets the current runable object. 
        /// </summary>
        IRunable CurrentRunableObject { get; }
        /// <summary>
        /// Gets the id of the task, normally, it should be a guid
        /// </summary>
        string ID { get; }
        /// <summary>
        /// Gets the name of the task
        /// </summary>
        string Name { get; }
        /// <summary>
        /// Gets the logger
        /// </summary>
        ILog Logger { get; }
        /// <summary>
        /// Gets the connection string
        /// </summary>
        string ConnectionString { get; }
        /// <summary>
        /// Gets the task is stopped or not
        /// </summary>
        bool Stopped { get; }
        /// <summary>
        /// Gets the task is paused or not
        /// </summary>
        bool Paused { get; }
        /// <summary>
        /// Gets or sets if the task can cache the process context to go back the process flow.
        /// </summary>
        bool SupportCache { get; set; }

        /// <summary>
        /// Initializes the task with configuration file
        /// </summary>
        /// <param name="configurationFile"></param>
        /// <param name="name">The task name </param>
        /// <param name="id"></param>
        /// <param name="connectionString">The connection string for the database which is used to record the targets populated information for the host</param>
        bool InitByConfiguration(XmlDocument configurationFile, string name, string id, string connectionString);

        /// <summary>
        /// Runs this task.
        /// </summary>
        void Run();
        /// <summary>
        /// Stops this task.
        /// </summary>
        void Stop();
        /// <summary>
        /// Pauses this task.
        /// </summary>
        void Pause();
        /// <summary>
        /// Continue this task after it has been stopped.
        /// </summary>
        void Continue();
        /// <summary>
        /// Enter a runable object of this task.
        /// </summary>
        /// <param name="runableObject"></param>
        void EnterRunableObject(IRunable runableObject);
        /// <summary>
        /// Leave a runable object of this task
        /// </summary>
        /// <param name="runableObject"></param>
        void LeaveRunableObject(IRunable runableObject);

        /// <summary>
        /// When the current runable object changed, this event will be triggled.
        /// </summary>
        event Action<IRunable> EnterRunableObjectHandler;
        /// <summary>
        /// This event occurs when the runable executes all its logic and will leave
        /// </summary>
        event Action<IRunable> LeaveRunableObjectHandler;
    }
}
